<template>
  <div>
    <div class="crumbs">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item>
          <i class="el-icon-lx-cascades"></i>
          用户管理
        </el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    <div class="container">
      <div class="handle-box">
        <el-select v-model="query.type" placeholder="用户类型" class="handle-select mr10">
          <el-option key="0" label="管理员" value="0"></el-option>
          <el-option key="1" label="普通用户" value="1"></el-option>
          <el-option key="3" label="全部用户" value=""></el-option>
        </el-select>
        <el-input v-model="query.username" placeholder="用户名" class="handle-input mr10"></el-input>
        <el-button type="primary" @click="handleSearch"><el-icon style="margin-right: 5px">
            <Search />
          </el-icon>搜索</el-button>
        <el-button type="primary" @click="resetSearch">清空</el-button>
        <el-button type="primary" @click="handleAdd">添加用户</el-button>
        <el-button type="primary" @click="handleExportData"><el-icon style="margin-right: 5px">
            <Download />
          </el-icon>导出用户信息</el-button>
        <el-popconfirm title="确定要删除选中用户？" confirm-button-text="确定" cancel-button-text="取消" @confirm="deleteAll">
          <template #reference>
            <el-button type="danger">删除选中</el-button>
          </template>
        </el-popconfirm>
      </div>

      <el-table :data="tableData" class="table" ref="multipleTable" header-cell-class-name="table-header"
        @selection-change="handleSelect" v-loading="loading">
        <el-table-column type="selection" width="70" align="center" />
        <el-table-column label="序号" width="65" align="center" fixed>
          <template #default="scope">
            {{ scope.$index + 1 }}
          </template>
        </el-table-column>
        <el-table-column prop="username" label="用户名" width="100" fixed align="center"></el-table-column>
        <el-table-column prop="realname" label="真实姓名" width="100" align="center"></el-table-column>
        <el-table-column label="用户类型" width="100" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.type == '0'
                ? 'danger'
                : scope.row.type == '1'
                  ? 'success'
                  : 'warning'
              ">
              {{
                scope.row.type == '0'
                ? '管理员'
                : scope.row.type == '1'
                  ? '普通用户'
                  : '暂无'
              }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="性别" align="center" width="80">
          <template #default="scope">
            <el-tag :type="scope.row.gender == 'female' ? 'success' : ''">
              {{ scope.row.gender == 'female' ? '女' : '男' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="糖尿病类型" width="100" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.specialCondition == '0'
                ? 'success'
                : scope.row.specialCondition == '1'
                  ? 'danger'
                  : scope.row.specialCondition == '2'
                    ? 'danger'
                    : scope.row.specialCondition == '3'
                      ? 'danger'
                      : scope.row.specialCondition == '4'
                        ? 'danger'
                        : ''
              ">
              {{
                scope.row.specialCondition == '0'
                ? '正常'
                : scope.row.specialCondition == '1'
                  ? 'Ⅰ型'
                  : scope.row.specialCondition == '2'
                    ? 'Ⅱ型'
                    : scope.row.specialCondition == '3'
                      ? '混合型'
                      : scope.row.specialCondition == '4'
                        ? '其他特殊类型'
                        : '无'
              }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="用户状态" align="center" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status == '1'
                ? 'success'
                : scope.row.status == '0'
                  ? 'danger'
                  : ''
              ">
              {{
                scope.row.status == '1'
                ? '正常'
                : scope.row.status == '0'
                  ? '停用'
                  : '未知'
              }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="bmi" label="BMI值" width="100" align="center">
          <template #default="scope">
            <span v-if="scope.row.bmi == '' || scope.row.bmi == null">无</span>
            <span v-else>{{ scope.row.bmi }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="height" label="身高(cm)" width="100" align="center">
          <template #default="scope">
            <span v-if="scope.row.height == '' || scope.row.height == null">无</span>
            <span v-else>{{ scope.row.height }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="weight" label="体重(公斤)" width="100" align="center">
          <template #default="scope">
            <span v-if="scope.row.weight == '' || scope.row.weight == null">无</span>
            <span v-else>{{ scope.row.weight }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="birthDay" label="出生日期" width="180" align="center">
          <template #default="scope">
            <span v-if="scope.row.birthDay == '' || scope.row.birthDay == null">无</span>
            <span v-else>{{ scope.row.birthDay }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="创建日期" width="180" align="center">
          <template #default="scope">
            <span v-if="scope.row.createdAt == '' || scope.row.createdAt == null">无</span>
            <span v-else>{{ scope.row.createdAt }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="phone" width="180" label="联系电话" align="center">
          <template #default="scope">
            <span v-if="scope.row.phone != null || scope.row.phone != undefined">{{ scope.row.phone }}</span>
            <span v-else>无</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180" align="center">
          <template #default="scope">
            <el-button v-if="scope.row.type == 0" type="text" icon="el-icon-edit" disabled="true"><el-icon
                style="margin-right: 5px">
                <Edit />
              </el-icon>编辑</el-button>
            <el-button v-else type="text" icon="el-icon-edit" @click="handleEdit(scope.$index, scope.row)"><el-icon
                style="margin-right: 5px">
                <Edit />
              </el-icon>编辑</el-button>
            <el-popconfirm title="确定要删除此用户？" confirm-button-text="确定" cancel-button-text="取消"
              @confirm="handleDelete(scope.$index, scope.row)">
              <template #reference>
                <el-button size="small" type="danger" v-if="scope.row.type == 1"><el-icon style="margin-right: 5px">
                    <Delete />
                  </el-icon>删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination">
        <el-pagination v-if="totalCount" v-model:currentPage="query.currentPage" v-model:page-size="query.pageSize"
          layout="prev, pager, next, jumper" :total="totalCount"
          @current-change="handleCurrentChange(query.currentPage)" />
      </div>
    </div>
    <!-- 用户编辑 -->
    <el-dialog v-model="centerDialogVisible" title="用户编辑" width="40%">
      <div>
        <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" status-icon>
          <el-form-item label="用户名" prop="username">
            <el-input v-model="ruleForm.username" placeholder="请输入昵称"/>
          </el-form-item>
          <el-form-item label="真实姓名" prop="realname">
            <el-input v-model="ruleForm.realname" placeholder="请输入真实姓名"/>
          </el-form-item>
          <el-form-item label="身高" prop="height" >
            <el-input v-model="ruleForm.height" placeholder="请输入身高，单位为厘米"/>
          </el-form-item>
          <el-form-item label="体重" prop="weight" >
            <el-input v-model="ruleForm.weight" placeholder="请输入体重，单位为公斤"/>
          </el-form-item>
          <el-form-item label="电话号码" prop="phone">
            <el-input v-model="ruleForm.phone" placeholder="请输入电话号码"/>
          </el-form-item>
          <el-form-item label="BMI值" prop="bmi">
            <el-input v-model="ruleForm.bmi" disabled />
          </el-form-item>
          <el-form-item label="出生日期" prop="birthDay">
            <div>
              <div class="block">
                <el-date-picker v-model="ruleForm.birthDay" type="date" placeholder="请选择日期"
                  :disabled-date="disabledDate" :shortcuts="shortcuts" />
              </div>
            </div>
          </el-form-item>
          <el-form-item label="性别" prop="gender">
            <el-radio-group v-model="ruleForm.gender">
              <!-- <el-radio label="other">其他</el-radio> -->
              <el-radio label="female">女</el-radio>
              <el-radio value="male" label="male">男</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="糖尿病类型" prop="specialCondition">
            <el-radio-group v-model="ruleForm.specialCondition">
              <el-radio :label="0">正常</el-radio>
              <el-radio :label="1">Ⅰ型糖尿病</el-radio>
              <el-radio :label="2">Ⅱ型糖尿病</el-radio>
              <el-radio :label="3">混合型糖尿病</el-radio>
              <el-radio :label="4">其他特殊类型</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="用户类型" prop="type">
            <el-radio-group v-model="ruleForm.type">
              <el-radio :label="1">普通用户</el-radio>
              <el-radio :label="0">管理员</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="用户状态" prop="status">
            <el-radio-group v-model="ruleForm.status">
              <el-radio :label="0">停用</el-radio>
              <el-radio :label="1">正常</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitForm(ruleFormRef)">更新</el-button>
          <el-button @click="resetForm(ruleFormRef)">重置表单</el-button>
          <el-button @click="centerDialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { ref, reactive, onBeforeMount } from 'vue'
import request from '../../utils/request'
import { ElNotification } from 'element-plus'
import { useRouter } from 'vue-router'
// import {XLSX} from 'xlsx'
import XLSX from 'xlsx'
import qs from 'qs'
export default {
  setup() {
    const router = useRouter()

    const loading = ref(true)

    const resetForm = (formEl) => {
      if (!formEl) return
      formEl.resetFields()
    }
    const cancelForm = (formEl) => {
      centerDialogVisible.value = false
      centerDialogAddVisible.value = false
      resetForm(formEl)
    }
    // 处理时间函数
    function dateTOString(date) {
      var source = new Date(date)
      var yy = source.getFullYear().toString()
      var mm = source.getMonth() + 1
      mm = mm < 10 ? '0' + mm.toString() : mm.toString()
      var dd = source.getDate()
      dd = dd < 10 ? '0' + dd.toString() : dd.toString()
      var aa = yy + '-' + mm + '-' + dd
      return aa
    }
    //更新表单
    const submitForm = async (formEl) => {
      if (!formEl) return
      await formEl.validate((valid, fields) => {
        if (valid) {
          request
            .request({
              url: '/user/updateUser',
              method: 'post',
              data: {
                userId: ruleForm.userId,
                username: ruleForm.username,
                realname: ruleForm.realname,
                gender: ruleForm.gender,
                height: ruleForm.height,
                weight: ruleForm.weight,
                phone: ruleForm.phone,
                bmi: ruleForm.bmi,
                type: ruleForm.type,
                status: ruleForm.status,
                specialCondition: ruleForm.specialCondition,
                birthDay: dateTOString(ruleForm.birthDay),
              },
              timeout: 3000,
            })
            .then((res) => {
              if (res.data.code == 200) {
                ElNotification({
                  title: '更新成功',
                  message: '成功更新用户信息',
                })

                getData()
                centerDialogVisible.value = false
                // router.go(0)
              } else {
                ElNotification({
                  title: '更新失败',
                  message: '请联系管理员检查失败原因',
                })
              }
            })
            .catch((e) => {
              ElNotification({
                title: '更新失败',
                message: '请联系管理员检查失败原因',
              })
            })
        } else {
          ElNotification({
            title: '校验失败',
            message: '请重新填写信息',
          })
        }
      })
    }
    const ruleForm = reactive({
      birthDay: '',
      bmi: 0,
      createdAt: '',
      gender: '',
      height: 0,
      logoImg: '',
      phone: '',
      specialCondition: 0,
      status: 0,
      totalKcal: 0,
      type: 1,
      userId: '',
      username: '',
      weight: 0,
    })

    const checkHeight = (rule, value, callback) => {
      if (value > 250) {
        callback(new Error(rule.message))
      } else {
        callback()
      }
    }
    const checkWeight = (rule, value, callback) => {
      if (value > 300) {
        callback(new Error(rule.message))
      } else {
        callback()
      }
    }

    const checkPhone = (rule, value, callback) => {
      if (/^((0\d{2,3}-?\d{7,8})|(1[3465789]\d{9}))$/.test(value) == false) {
        callback(new Error(rule.message))
      } else {
        callback()
      }
    }
    //判断用户名是否存在
    const isExist = ref(false)
    const adminIsExist = ref(false)
    const beforeName = ref()
    const checkUserName = async (rule, value, callback) => {
      isExist.value = await handleExist()
      adminIsExist.value = await handleAdminIsExist()
      console.log(beforeName.value, 999999);
      console.log(ruleForm.username, 999999);
      if (beforeName.value != ruleForm.username &&(isExist.value == true || adminIsExist.value == true)) {
        callback(new Error(rule.message))
      } else {
        callback()
      }
    }

    const lxfs = /^((0\d{2,3}-?\d{7,8})|(1[3465789]\d{9}))$/ //验证电话

    const rules = reactive({
      username: [
        {
          required: true,
          message: '请输入用户名',
          trigger: 'change',
        },
        {
          validator: checkUserName,
          message: '用户名重复，请重新输入',
        }
      ],
      realname: [
        {
          required: false,
          message: '请输入真实姓名',
          trigger: 'blur',
        },
      ],
      password: [
        {
          required: true,
          message: '请输入密码',
          trigger: 'blur',
        },
      ],
      gender: [
        {
          required: true,
          message: '请选择性别',
          trigger: 'change',
        },
      ],
      height: [
        {
          required: true,
          message: '请输入身高',
          trigger: 'blur',
        },
        {
          validator: checkHeight,
          message: '请输入正确的身高(0~250)',
        },
      ],
      weight: [
        {
          required: true,
          message: '请输入体重',
          trigger: 'blur',
        },
        {
          validator: checkWeight,
          message: '请输入正确的体重(0~300)',
        },
      ],
      phone: [
        {
          required: false,
          message: '请输入电话号码',
          trigger: 'blur',
        },
        {
          validator: checkPhone,
          message: '请输入正确的电话号码',
        },
      ],
      birthDay: [
        {
          required: true,
          message: '请选择出生日期值',
          trigger: 'change',
        },
      ],
      specialCondition: [
        {
          required: true,
          message: '请选择特殊类型',
          trigger: 'change',
        },
      ],
    })
    const ruleFormRef = ref()
    const centerDialogVisible = ref(false)
    const centerDialogAddVisible = ref(false)
    const query = reactive({
      address: '',
      username: '',
      currentPage: 1,
      pageSize: 5,
    })
    const tableData = ref([])
    const totalCount = ref(0)
    //判断用户名是否存在
    /* const isExist = ref(false)
    const adminIsExist = ref(false) */
    const handleExist = async () => {
      return await request
        .request({
          url: '/user/getUserIsExist',
          method: 'get',
          params: {
            username: ruleForm.username,
          },
        })
        .then((res) => {
          return res.data.data.isExist
          // }
        })
    }
    const handleAdminIsExist = async () => {
      return await request
        .request({
          url: '/user/getAdminIsExist',
          method: 'get',
          params: {
            username: ruleForm.username,
          },
        })
        .then((res) => {
          return res.data.data.isExist
          // }
        })
    }

    // 获取表格数据
    const getData = () => {
      request
        .request({
          url: '/user/getUsersByPageAndCondition',
          params: {
            type: query.type,
            username: query.username,
            currentPage: query.currentPage,
            pageSize: query.pageSize,
          },
          method: 'get',
        })
        .then((res) => {
          //获取当前页的数据
          tableData.value = res.data.data.rows
          //获取总记录数
          totalCount.value = res.data.data.count
          loading.value = false
        })
        .catch((e) => {
          console.log(e)
        })
    }
    getData()
    // 查询操作
    const handleSearch = () => {
      getData()
    }
    // 分页导航
    const handleCurrentChange = (val) => {
      loading.value = true
      query.currentPage = val
      getData()
    }

    //批量删除
    const selectArray = ref('')
    //选中
    const handleSelect = (val) => {
      selectArray.value = []
      for (const iterator of val) {
        selectArray.value.push(iterator.userId)
      }
    }
    //删除全部选中
    const deleteAll = () => {
      loading.value = true
      request
        .request({
          url: '/user/deleteUser',
          method: 'get',
          params: {
            userIds: selectArray.value,
          },
          paramsSerializer: (params) => {
            return qs.stringify(params, { indices: false })
          },
        })
        .then((res) => {
          if (res.data.message == 'success') {
            getData()
            ElNotification({
              title: '删除成功',
              message: '成功删除用户信息',
            })
            loading.value = false
          } else {
            ElNotification({
              title: '删除失败',
              message: '请联系管理员检查失败原因',
            })
          }
        })
        .catch((e) => {
          ElNotification({
            title: '删除失败',
            message: '请联系管理员检查失败原因',
          })
        })
    }
    // 删除操作
    const handleDelete = (index, row) => {
      loading.value = true
      request
        .request({
          url: '/user/deleteUser?userIds=' + row.userId,
          method: 'get',
          params: {
            userId: row.userId,
          },
        })
        .then((res) => {
          if (res.data.code == '200') {
            getData()
            ElNotification({
              title: '删除成功',
              message: '成功删除用户信息',
            })
          } else {
            ElNotification({
              title: '删除失败',
              message: '请联系管理员检查失败原因',
            })
          }
        })
        .catch((e) => {
          ElNotification({
            title: '删除失败',
            message: '请联系管理员检查失败原因',
          })
        })
    }
    const handleEdit = (index, row) => {
      centerDialogVisible.value = true
      ruleForm.userId = row.userId
      ruleForm.username = row.username
      beforeName.value = row.username
      ruleForm.realname = row.realname
      ruleForm.gender = row.gender
      ruleForm.birthDay = row.birthDay
      ruleForm.bmi = row.bmi
      ruleForm.gender = row.gender
      ruleForm.height = row.height
      ruleForm.weight = row.weight
      ruleForm.logoImg = row.logoImg
      ruleForm.phone = row.phone
      ruleForm.specialCondition = row.specialCondition
      ruleForm.status = row.status
      ruleForm.totalKcal = row.totalKcal
      ruleForm.type = row.type
    }
    // 清空
    const resetSearch = () => {
      query.type = ''
      query.username = ''
      getData()
    }
    //添加用户
    const handleAdd = () => {
      router.push('userAdd')
    }
    /*
    * @description:
    * @param {Object} json 服务端发过来的数据
    * @param {String} name 导出Excel文件名字
   
    * @param {String} titleArr 导出Excel表头
   
    * @param {String} sheetName 导出sheetName名字
    * @return:
    */
    const exportData = ref([])
    const titleArr = [
      '创建时间',
      '更新时间',
      '用户ID',
      '用户名',
      '真实姓名',
      '性别',
      '身高',
      '体重',
      '联系电话',
      'BMI',
      '糖尿病类型(0无 1-1型糖尿病 2-2型糖尿病 3-混合型糖尿病 4-其他特殊类型)',
      '用户类型(0-管理员 1-普通用户)',
      '用户状态(0-停用 1-正常)',
      '出生日期',
    ] //表头中文名
    // 获取导出表格数据
    const handleExportData = () => {
      request
        .request({
          url: '/user/getAllUsers',
          method: 'get',
        })
        .then((res) => {
          //获取当前页的数据
          exportData.value = res.data.data
          exportExcel(exportData.value, 'test', titleArr, 'sheetName')
        })
        .catch((e) => {
          console.log(e)
        })
        .finally()
    }
    // 导出函数
    const exportExcel = (json, name, titleArr, sheetName) => {
      /* convert state to workbook */
      var data = new Array()
      var keyArray = new Array()
      const getLength = function (obj) {
        var count = 0
        for (var i in obj) {
          if (obj.hasOwnProperty.call(i)) {
            count++
          }
        }
        return count
      }

      for (const key1 in json) {
        if (Object.prototype.hasOwnProperty.call(json, key1)) {
          const element = json[key1]
          var rowDataArray = new Array()
          for (const key2 in element) {
            if (
              key2 == 'password' ||
              key2 == 'logoImg' ||
              key2 == 'totalKcal'
            ) {
              continue
            }
            if (Object.hasOwnProperty.call(element, key2)) {
              var element2 = ''
              if (key2 == 'gender') {
                if (element[key2] == 'male') {
                  element2 = '男'
                } else if (element[key2] == 'female') {
                  element2 = '女'
                } else {
                  element2 = '其他'
                }
                // element2 = element[key2] == 'male' ? '男' : '女'
              } else if (key2 == 'specialCondition') {
                //糖尿病类型 0无 1-1型糖尿病 2-2型糖尿病 3-混合型糖尿病 4-其他特殊类型
                // element2 = element[key2] == '1'?'男':'女'
                if (element[key2] == 0) {
                  element2 = '正常'
                } else if (element[key2] == 1) {
                  element2 = '1型糖尿病'
                } else if (element[key2] == 2) {
                  element2 = '2型糖尿病'
                } else if (element[key2] == 3) {
                  element2 = '混合型糖尿病'
                } else if (element[key2] == 4) {
                  element2 = '其他特殊类型'
                } else {
                  element2 = '无'
                }
              } else if (key2 == 'type') {
                if (element[key2] == 0) {
                  element2 = '管理员'
                } else {
                  element2 = '普通用户'
                }
              } else if (key2 == 'status') {
                if (element[key2] == 0) {
                  element2 = '停用'
                } else {
                  element2 = '正常'
                }
              } else {
                element2 = element[key2]
              }
              // element2 = element[key2]
              rowDataArray.push(element2)
              if (keyArray.length < getLength(element)) {
                keyArray.push(key2)
              }
            }
          }
          data.push(rowDataArray)
        }
      }
      // keyArray为英文字段表头
      data.splice(0, 0, keyArray, titleArr)
      const ws = XLSX.utils.aoa_to_sheet(data)
      const wb = XLSX.utils.book_new()
      // 此处隐藏英文字段表头
      var wsrows = [{ hidden: true }]
      ws['!rows'] = wsrows // ws - worksheet
      XLSX.utils.book_append_sheet(wb, ws, sheetName)
      /* generate file and send to client */
      XLSX.writeFile(wb, name + '.xlsx')
    }
    // onBeforeMount(getData)
    return {
      loading,
      resetForm,
      cancelForm,
      ruleFormRef,
      submitForm,
      ruleForm,
      rules,
      centerDialogVisible,
      centerDialogAddVisible,
      query,
      totalCount,
      tableData,
      getData,
      handleEdit,
      handleSearch,
      handleCurrentChange,
      handleDelete,
      handleAdd,
      handleSelect,
      selectArray,
      deleteAll,
      dateTOString,
      exportExcel,
      handleExportData,
      resetSearch,
      exportData,
      titleArr,
    }
  },
}
</script>
<style lang="scss" scoped>
.demonstration {
  display: block;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  margin-bottom: 20px;
}

.handle-box {
  margin-bottom: 20px;
}

.handle-select {
  width: 120px;
}

.handle-input {
  width: 300px;
  display: inline-block;
}

.table {
  width: 100%;
  font-size: 14px;
}

.red {
  color: #ff0000;
}

.mr10 {
  margin-right: 10px;
}

.table-td-thumb {
  display: block;
  margin: auto;
  width: 40px;
  height: 40px;
}

.demo-date-picker {
  display: flex;
  width: 100%;
  padding: 0;
  flex-wrap: wrap;
}

.demo-date-picker .block {
  // padding: 30px 0;
  text-align: center;
  border-right: solid 1px var(--el-border-color);
  flex: 1;
}

.demo-date-picker .block:last-child {
  border-right: none;
}

.demo-date-picker .container {
  flex: 1;
  border-right: solid 1px var(--el-border-color);
}

.demo-date-picker .container .block {
  border-right: none;
}

.demo-date-picker .container .block:last-child {
  border-top: solid 1px var(--el-border-color);
}

.demo-date-picker .container:last-child {
  border-right: none;
}

.demo-date-picker {
  display: block;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  margin-bottom: 20px;
}
</style>
